/*
 * Source code written by Tácio S. Diogo.
 * Email: taciosd@gmail.com
 * Any copy or use without permission is prohibited.
 */
package app.comportamentos;

import app.agentes.Cidadao;
import app.modelo.Ambiente;
import app.modelo.Console;
import app.modelo.Constantes;
import jade.core.AID;
import jade.core.behaviours.CyclicBehaviour;
import jade.domain.AMSService;
import jade.domain.FIPAAgentManagement.AMSAgentDescription;
import jade.domain.FIPAAgentManagement.SearchConstraints;
import jade.domain.FIPAException;
import jade.lang.acl.ACLMessage;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Tácio S. Diogo
 */
public class ContarVotos extends CyclicBehaviour {
    public boolean pedidoFeito = false;
    private Calendar tempoFim;
    private HashMap<String, Integer> votacoes = new HashMap<String, Integer>();
    
    public ContarVotos() {
    }

    @Override
    public void action() {
        
        if (!pedidoFeito) {
            try {
                fazerPedidoDeVotos();
                Console.escrever(myAgent, "Aguardando fim do prazo para votacao...");
            } catch (FIPAException ex) {
                Logger.getLogger(ContarVotos.class.getName()).log(Level.SEVERE, null, ex);
            }
        } else {
            Calendar tempoAtual = Calendar.getInstance();
            boolean tempoAcabou = (tempoAtual.after(tempoFim));
            if (tempoAcabou) {
                divulgarResultado();
                terminarContagem();
            } else {
                receberVotacoes();
            }
        }
    }

    private void fazerPedidoDeVotos() throws FIPAException {
        Console.escrever(myAgent, "Pedindo votos dos eleitores...");
        ACLMessage msg = new ACLMessage(ACLMessage.REQUEST);
        msg.setContent(Constantes.PEDIDO_VOTO);
        
        SearchConstraints constraints = new SearchConstraints();
        constraints.setMaxResults(new Long(-1));
                
        List<Cidadao> listaCidadao = Ambiente.getInstance().getCidadaos();
        for(Cidadao cidadao : listaCidadao){
            msg.addReceiver(cidadao.getAID());
        }
        
        myAgent.send(msg);
        pedidoFeito = true;
        
        tempoFim = (Calendar) Calendar.getInstance();
        tempoFim.add(Calendar.MINUTE, 1);
    }

    private void receberVotacoes() {
        ACLMessage msg = myAgent.receive();
        if (msg == null || (!msg.getConversationId().equals("Voto")))
            return;
        
        String nomeCandidato = msg.getContent();
        if (!votacoes.containsKey(nomeCandidato)) {
            votacoes.put(nomeCandidato, 1);
        } else {
            Integer votos = votacoes.get(nomeCandidato);
            votacoes.put(nomeCandidato, votos+1);
        }
    }

    private void divulgarResultado() {
        Console.escrever(myAgent, "=== Resultados ===");
        Set<Entry<String, Integer>> votos = votacoes.entrySet();
        Iterator it = votos.iterator();
        while (it.hasNext()) {
            Entry<String, Integer> candidato = (Entry<String, Integer>) it.next();
            String nomeCandidato = candidato.getKey();
            Integer numeroVotos = candidato.getValue();
            Console.escrever(myAgent, "Candidato: " + nomeCandidato + 
                                        " -> " + String.valueOf(numeroVotos) + " votos");
        }
    }

    private void terminarContagem() {
        myAgent.removeBehaviour(this);
    }
}
